<?php

namespace app\admin\controller\manufacture;

use app\common\controller\Backend;
use think\Db;

/**
 * 大屏看板
 *
 * @icon fa fa-tachometer
 * @remark 制造执行系统大屏看板
 */
class Dashboard extends Backend
{
    /**
     * 大屏看板首页
     */
    public function index()
    {
        // 获取实时数据
        $data = $this->getRealTimeData();
        $this->view->assign('data', $data);
        
        return $this->view->fetch();
    }

    /**
     * 获取实时数据
     */
    private function getRealTimeData()
    {
        $data = [];
        
        // 生产计划数据
        $data['plan'] = [
            'total' => \app\admin\model\manufacture\Plan::count(),
            'running' => \app\admin\model\manufacture\Plan::where('status', 'running')->count(),
            'completed' => \app\admin\model\manufacture\Plan::where('status', 'completed')->count(),
            'pending' => \app\admin\model\manufacture\Plan::where('status', 'pending')->count(),
        ];
        
        // 物料库存数据
        $data['material'] = [
            'total' => \app\admin\model\manufacture\Material::count(),
            'low_stock' => \app\admin\model\manufacture\Stock::alias('s')
                ->join('manufacture_material m', 's.material_id = m.id')
                ->where('s.quantity', '<=', Db::raw('m.min_stock'))
                ->where('m.min_stock', '>', 0)
                ->count(),
            'total_stock' => \app\admin\model\manufacture\Stock::sum('quantity'),
        ];
        
        // 设备状态数据
        $data['equipment'] = [
            'total' => \app\admin\model\manufacture\Equipment::count(),
            'normal' => \app\admin\model\manufacture\Equipment::where('status', 'normal')->count(),
            'maintenance' => \app\admin\model\manufacture\Equipment::where('status', 'maintenance')->count(),
            'fault' => \app\admin\model\manufacture\Equipment::where('status', 'fault')->count(),
            'idle' => \app\admin\model\manufacture\Equipment::where('status', 'idle')->count(),
        ];
        
        // 质量数据
        $data['quality'] = [
            'total' => \app\admin\model\manufacture\Quality::count(),
            'pass' => \app\admin\model\manufacture\Quality::where('result', 'pass')->count(),
            'fail' => \app\admin\model\manufacture\Quality::where('result', 'fail')->count(),
            'pass_rate' => 0,
        ];
        
        if ($data['quality']['total'] > 0) {
            $data['quality']['pass_rate'] = round(($data['quality']['pass'] / $data['quality']['total']) * 100, 2);
        }
        
        // 今日数据
        $data['today'] = [
            'plan_created' => \app\admin\model\manufacture\Plan::whereTime('createtime', 'today')->count(),
            'plan_completed' => \app\admin\model\manufacture\Plan::whereTime('updatetime', 'today')->where('status', 'completed')->count(),
            'quality_checked' => \app\admin\model\manufacture\Quality::whereTime('createtime', 'today')->count(),
            'stock_in' => \app\admin\model\manufacture\StockLog::whereTime('createtime', 'today')->where('type', 'in')->sum('quantity'),
            'stock_out' => \app\admin\model\manufacture\StockLog::whereTime('createtime', 'today')->where('type', 'out')->sum('quantity'),
        ];
        
        // 本月数据
        $data['month'] = [
            'plan_created' => \app\admin\model\manufacture\Plan::whereTime('createtime', 'month')->count(),
            'plan_completed' => \app\admin\model\manufacture\Plan::whereTime('updatetime', 'month')->where('status', 'completed')->count(),
            'quality_checked' => \app\admin\model\manufacture\Quality::whereTime('createtime', 'month')->count(),
            'stock_in' => \app\admin\model\manufacture\StockLog::whereTime('createtime', 'month')->where('type', 'in')->sum('quantity'),
            'stock_out' => \app\admin\model\manufacture\StockLog::whereTime('createtime', 'month')->where('type', 'out')->sum('quantity'),
        ];
        
        return $data;
    }

    /**
     * 获取图表数据
     */
    public function chartData()
    {
        $type = $this->request->get('type', 'production');
        
        switch ($type) {
            case 'production':
                $data = $this->getProductionChartData();
                break;
            case 'quality':
                $data = $this->getQualityChartData();
                break;
            case 'equipment':
                $data = $this->getEquipmentChartData();
                break;
            case 'stock':
                $data = $this->getStockChartData();
                break;
            default:
                $data = [];
        }
        
        return json($data);
    }

    /**
     * 生产数据图表
     */
    private function getProductionChartData()
    {
        $data = [];
        
        // 最近7天的生产计划数据
        for ($i = 6; $i >= 0; $i--) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $created = \app\admin\model\manufacture\Plan::whereTime('createtime', $date)->count();
            $completed = \app\admin\model\manufacture\Plan::whereTime('updatetime', $date)->where('status', 'completed')->count();
            
            $data['dates'][] = date('m-d', strtotime($date));
            $data['created'][] = $created;
            $data['completed'][] = $completed;
        }
        
        return $data;
    }

    /**
     * 质量数据图表
     */
    private function getQualityChartData()
    {
        $data = [];
        
        // 最近7天的质检数据
        for ($i = 6; $i >= 0; $i--) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $total = \app\admin\model\manufacture\Quality::whereTime('createtime', $date)->count();
            $pass = \app\admin\model\manufacture\Quality::whereTime('createtime', $date)->where('result', 'pass')->count();
            $passRate = $total > 0 ? round(($pass / $total) * 100, 2) : 0;
            
            $data['dates'][] = date('m-d', strtotime($date));
            $data['total'][] = $total;
            $data['pass_rate'][] = $passRate;
        }
        
        return $data;
    }

    /**
     * 设备数据图表
     */
    private function getEquipmentChartData()
    {
        $data = [];
        
        // 设备状态分布
        $data['status'] = [
            'normal' => \app\admin\model\manufacture\Equipment::where('status', 'normal')->count(),
            'maintenance' => \app\admin\model\manufacture\Equipment::where('status', 'maintenance')->count(),
            'fault' => \app\admin\model\manufacture\Equipment::where('status', 'fault')->count(),
            'idle' => \app\admin\model\manufacture\Equipment::where('status', 'idle')->count(),
        ];
        
        // 设备类型分布
        $data['type'] = [
            'production' => \app\admin\model\manufacture\Equipment::where('type', 'production')->count(),
            'auxiliary' => \app\admin\model\manufacture\Equipment::where('type', 'auxiliary')->count(),
            'testing' => \app\admin\model\manufacture\Equipment::where('type', 'testing')->count(),
            'transport' => \app\admin\model\manufacture\Equipment::where('type', 'transport')->count(),
        ];
        
        return $data;
    }

    /**
     * 库存数据图表
     */
    private function getStockChartData()
    {
        $data = [];
        
        // 最近7天的库存变动
        for ($i = 6; $i >= 0; $i--) {
            $date = date('Y-m-d', strtotime("-{$i} days"));
            $in = \app\admin\model\manufacture\StockLog::whereTime('createtime', $date)->where('type', 'in')->sum('quantity');
            $out = \app\admin\model\manufacture\StockLog::whereTime('createtime', $date)->where('type', 'out')->sum('quantity');
            
            $data['dates'][] = date('m-d', strtotime($date));
            $data['in'][] = $in ?: 0;
            $data['out'][] = $out ?: 0;
        }
        
        return $data;
    }

    /**
     * 获取实时列表数据
     */
    public function realTimeData()
    {
        $type = $this->request->get('type', 'plan');
        
        switch ($type) {
            case 'plan':
                $data = \app\admin\model\manufacture\Plan::with(['order'])
                    ->where('status', 'running')
                    ->order('priority desc, createtime desc')
                    ->limit(10)
                    ->select();
                break;
            case 'equipment':
                $data = \app\admin\model\manufacture\Equipment::with(['category'])
                    ->where('status', 'fault')
                    ->order('createtime desc')
                    ->limit(10)
                    ->select();
                break;
            case 'stock':
                $data = \app\admin\model\manufacture\Stock::alias('s')
                    ->join('manufacture_material m', 's.material_id = m.id')
                    ->join('manufacture_warehouse w', 's.warehouse_id = w.id')
                    ->where('s.quantity', '<=', Db::raw('m.min_stock'))
                    ->where('m.min_stock', '>', 0)
                    ->field('s.*, m.material_name, m.min_stock, w.warehouse_name')
                    ->order('s.quantity asc')
                    ->limit(10)
                    ->select();
                break;
            case 'order_progress':
                $data = $this->getOrderProgressData();
                break;
            case 'work_records':
                $data = $this->getWorkRecordsData();
                break;
            default:
                $data = [];
        }
        
        return json($data);
    }

    /**
     * 获取订单进度数据
     */
    private function getOrderProgressData()
    {
        // 获取正在执行的订单
        $orders = \app\admin\model\scanwork\Order::where('status', 1)
            ->order('createtime desc')
            ->limit(10)
            ->select();
        
        $data = [];
        foreach ($orders as $order) {
            $progress = $this->calculateOrderProgress($order->id);
            $data[] = [
                'order_id' => $order->id,
                'order_no' => $order->order_no,
                'customer_name' => $order->customer_name,
                'total_quantity' => $order->total_quantity,
                'overall_progress' => $progress['overall_progress'],
                'status' => $progress['status']
            ];
        }
        
        return $data;
    }

    /**
     * 获取报工记录数据
     */
    private function getWorkRecordsData()
    {
        $data = \app\admin\model\scanwork\WorkRecord::alias('wr')
            ->join('scanwork_order o', 'wr.order_id = o.id')
            ->join('scanwork_process p', 'wr.process_id = p.id')
            ->field('wr.*, o.order_no, p.name as process_name')
            ->order('wr.createtime desc')
            ->limit(10)
            ->select();
        
        return $data;
    }

    /**
     * 计算订单进度
     */
    private function calculateOrderProgress($orderId)
    {
        // 获取订单信息
        $order = \app\admin\model\scanwork\Order::find($orderId);
        if (!$order) {
            return ['overall_progress' => 0, 'status' => 'unknown'];
        }
        
        // 获取工序列表
        $processes = \app\admin\model\scanwork\Process::order('sequence')->select();
        
        // 获取报工记录
        $workRecords = \app\admin\model\scanwork\WorkRecord::where('order_id', $orderId)
            ->field('process_id, SUM(quantity) as completed_quantity')
            ->group('process_id')
            ->select();
        
        $workRecordMap = [];
        foreach ($workRecords as $record) {
            $workRecordMap[$record->process_id] = $record->completed_quantity;
        }
        
        // 计算总体进度
        $totalProgress = 0;
        $completedProcesses = 0;
        
        foreach ($processes as $process) {
            $completedQuantity = isset($workRecordMap[$process->id]) ? $workRecordMap[$process->id] : 0;
            $progressRate = $order->total_quantity > 0 ? round(($completedQuantity / $order->total_quantity) * 100, 2) : 0;
            $totalProgress += $progressRate;
            
            if ($completedQuantity >= $order->total_quantity) {
                $completedProcesses++;
            }
        }
        
        $overallProgress = count($processes) > 0 ? round($totalProgress / count($processes), 2) : 0;
        
        // 判断状态
        if ($completedProcesses == count($processes)) {
            $status = 'completed';
        } elseif ($completedProcesses > 0) {
            $status = 'in_progress';
        } else {
            $status = 'pending';
        }
        
        return [
            'overall_progress' => $overallProgress,
            'status' => $status
        ];
    }
}
